本篇文章同步發布於 Python 如何使用 Tkinter 套件建立能上傳 Excel 檔案的介面?【Python 處理 Excel #27】
既然系列文的主題是《Python 處理 Excel》,學習或實際操作一定有讀取 Excel 檔案的時候。這篇文章介紹如何透過 Python 的 Tkinter 套件建立基本的圖形使用者介面 (GUI),讓程式能接收使用者上傳的 Excel 檔案位置,對檔案進行處理,再把處理完的結果輸出到指定的 Excel 檔案位置。
平時都說要上傳檔案到某個地方,可是從電腦運作的角度而言,上傳這件事代表的是告訴電腦軟體/服務/平台檔案在電腦上的位置。同理,寫程式時如果需要讓程式讀取檔案,也需要提供檔案的位置給程式,程式才有辦法讀取檔案。以下分享 3 種寫程式時提供檔案位置的方法。
提供檔案位置最簡單的方式是把檔案位置寫死在程式中,用變數代表檔案位置會好維護一些,只是需要讀取多個檔案時,反覆修改檢查每個變數的檔案名稱是否正確依然不太方便。
使用程式解讀資料夾中的檔案名稱,進而找到需要的檔案位置也是一個方法,我在更新日常報表時就使用這個方法,這樣只需要在下載原始資料時按照規則命名檔案,後續就不用打開程式修改檔案名稱,程式會自己判斷檔案位置。舉例來說,我可能會讓程式在「下載」資料夾中,找所有名稱包含「訂單清單」的 Excel 檔案,然後選擇最新且符合條件的檔案作為程式的來源資料。
檔案位置是很瑣碎的資訊,多或少一個字都會造成程式找不到正確的檔案。對人來說,要輸入檔案的絕對位置或相對位置並不直觀,大部分的人頂多記得檔案名稱和放在哪一個資料夾,因此提供視窗介面讓使用者用「選」的選出檔案,是在檔案名稱和檔案存放位置不固定時很好的替代方案,湊出完整檔案路徑的功夫就交由背後的程式處理吧。
方法 3 是這篇文章介紹的重點。
Tkinter 是 Python 的內建 GUI 套件,用於構建桌面應用程式。這次我們將利用它來製作一個介面,讓使用者上傳 Excel 檔案。由於 Tkinter 是 Python 標準函式庫的一部分,無需額外安裝。
這篇文章的案例背景與資料沿用《Python pandas 使用 concat 將不同 DataFrame 垂直連接在一起》的內容。公司每個月會發布不同版本的銷售預測資料,這些檔案存儲於電腦的某個資料夾中,檔案以不同版本代號命名,例如 S1、S2、S3。
這篇文章的目標是建立一個上傳介面讓非技術人員也能完成檔案合併的任務,將兩個不同時間版本的銷售預測資料合併為一個檔案。
下方是其中一個銷售預測檔案的部分資料 (含標題):
create_date | version | period | customer_name | product | quantity |
---|---|---|---|---|---|
2024/2/1 | S2 | 2024/004 | Coolify | Laptop Pro | 500 |
2024/2/1 | S2 | 2024/004 | Coolify | Ultrabook | 300 |
2024/2/1 | S2 | 2024/004 | Nexida | Laptop Pro | 100 |
2024/2/1 | S2 | 2024/004 | Stella Tech | Laptop Pro | 300 |
資料中的 period
欄位表示針對哪個年份/月份進行銷售預測。
我們可以使用 Tkinter 的 filedialog.askopenfilename
實現 Excel 檔案選擇。這個功能讓使用者透過瀏覽檔案資料夾選擇想要上傳的檔案。下方是 Tkinter 檔案選擇程式碼:
import tkinter as tk
from tkinter import filedialog
# 建立主視窗
root = tk.Tk()
root.withdraw() # 隱藏主視窗
# 打開檔案選擇對話框
file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")])
print(f"選擇的檔案位置:{file_path}")
這段程式碼使用 tk.Tk()
建立一個主視窗,但隨後立即調用 root.withdraw()
隱藏這個主視窗,直接顯示檔案選擇對話框。
filedialog
模組中的 askopenfilename
方法打開一個檔案選擇對話框,並過濾出檔案類型為 .xlsx
的 Excel 檔案。使用者選中的檔案位置會存儲在變數 file_path
中。
這篇文章使用 pandas 合併兩個 Excel 檔案資料。由於這兩個檔案欄位結構相同,我們可以使用 pandas.concat()
進行合併。
import pandas as pd
# 讀取兩個 Excel 檔案
df1 = pd.read_excel("file1.xlsx")
df2 = pd.read_excel("file2.xlsx")
# 合併兩個 DataFrame
merged_df = pd.concat([df1, df2])
# 將結果輸出到 Excel 檔案
output_path = "merged_output.xlsx"
merged_df.to_excel(output_path, index=False)
print(f"已將合併結果儲存至:{output_path}")
以下程式碼案例結合 Tkinter 的檔案上傳功能與 pandas 的資料合併操作:
import tkinter as tk
from tkinter import filedialog
import pandas as pd
import os
def merge_files():
"""上傳兩個 Excel 檔案,進行檔案合併,並輸出結果到下載資料夾。
Raises:
ValueError: 若未選擇檔案則報錯。
"""
# 建立主視窗
root = tk.Tk()
root.withdraw() # 隱藏主視窗
# 選擇兩個 Excel 檔案
file_path1 = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")], title="選擇第一個 Excel 檔案")
file_path2 = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx")], title="選擇第二個 Excel 檔案")
# 檢查是否選擇檔案
if not file_path1 or not file_path2:
raise ValueError("必須選擇兩個檔案進行合併!")
# 讀取 Excel 檔案
df1 = pd.read_excel(file_path1)
df2 = pd.read_excel(file_path2)
# 合併兩個 DataFrame
merged_df = pd.concat([df1, df2])
# 獲取下載資料夾的位置
download_folder = os.path.join(os.path.expanduser("~"), "Downloads")
output_path = os.path.join(download_folder, "merged_output.xlsx")
# 將結果輸出到 Excel 檔案
merged_df.to_excel(output_path, index=False)
print(f"已將合併結果儲存至:{output_path}")
# 執行合併操作
merge_files()
這段程式碼做了以下幾件事情:
.xlsx
格式)。pandas.concat()
可以合併結構相同的 Excel 檔案。filedialog.askopenfilename
可以讓使用者選擇檔案,並將檔案位置傳給 pandas 進行處理。to_excel()
輸出到 Excel 檔案,並儲存到使用者的指定的資料夾位置。本篇文章同步發布於 Python 如何使用 Tkinter 套件建立能上傳 Excel 檔案的介面?【Python 處理 Excel #27】